package org.mmtk.plan.scale.balance;

import org.mmtk.plan.scale.Scale;
import org.mmtk.plan.scale.ScaleCollector;
import org.mmtk.plan.scale.ScaleTrace;
import org.mmtk.vm.VM;
import org.vmmagic.pragma.Inline;
import org.vmmagic.pragma.Uninterruptible;

@Uninterruptible
public class SBalanceCollector extends ScaleCollector {

	/****************************************************************************
	 * Instance fields
	 */
	private TraceBranchBalancer ballancer;
	private SBalanceTraceLocal sBalanceTraceLocal;
	private SBalanceTraceLocal sBalancePrivateTraceLocal;

	/****************************************************************************
	 * Initialization
	 */

	/**
	 * Constructor
	 */
	protected SBalanceCollector() {
		this.sBalanceTraceLocal = new SBalanceTraceLocal("sBalanceTraceLocal", global().scaleTrace);
		this.traceLocal = sBalanceTraceLocal;
		this.ballancer = global().ballancer;
		if(VM.activePlan.collectorCount() > 1) {
			this.multiThreaded = true;
			privateScaleTrace = new ScaleTrace(Scale.metaDataSpace);
			sBalancePrivateTraceLocal = new SBalanceTraceLocal("sBalancePrivateTraceLocal", SBalance.PRIVATE_SCAN_BALANCE, privateScaleTrace);
			this.privateTraceLocal = sBalancePrivateTraceLocal;		
		}
		else {
			this.multiThreaded = false;
			privateScaleTrace = null;
			this.privateTraceLocal = null;
		}		
	}

	/****************************************************************************
	 * 
	 * Collection
	 */

	/**
	 * Perform a per-collector collection phase.
	 * 
	 * @param phaseId
	 *            The collection phase to perform
	 * @param primary
	 *            Perform any single-threaded activities using this thread.
	 */
	@Inline
	@Override
	public void collectionPhase(short phaseId, boolean primary) {
		super.collectionPhase(phaseId, primary);
	}
	
	protected void doFixClosure(boolean primary) {
		if(primary) {
			sBalanceTraceLocal.completeFixTrace(ballancer, true);
		}
	}
	
	/****************************************************************************
	 * 
	 * Miscellaneous
	 */

	/** @return The active global plan as an <code>MS</code> instance. */
	@Inline
	private static SBalance global() {
		return (SBalance) VM.activePlan.global();
	}
}
